require 'vector'
require 'yaml'

class GameObject
  @@load_path = "."
  
  attr_accessor :game_type, :name, :color
  attr_accessor :position
  attr_accessor :thrust, :throttle, :speed, :max_speed
  attr_reader :accelleration
  attr_accessor :rotation, :rotation_speed, :rotation_vector
  attr_accessor :height, :width
  
  def self.load_path=(path)
    @@load_path = path
  end
  
  def self.load_path
    @@load_path
  end
  
  def initialize(position = nil)
    @position = position.nil? ? Point.new(0, 0) : Point.new(position)
    
    @accelleration = 0
    @max_speed = 0
    @speed = 0
    @thrust = 0
    @throttle = 0
    
    @rotation = 0
    @rotation_speed = 0
    @height, @width = 0
  end
  
  def self.load(source)
    obj = GameObject.new
    obj.game_type = source.to_sym
    
    definition = YAML::load_file("#{@@load_path}/#{source}.yml")
    definition.each do |k, v|
      obj.send("#{k}=".to_sym, v) if obj.respond_to?("#{k}=".to_sym)
    end
    
    obj
  end
  
  # Updates the objects state. Accepts a Game object.
  def update(game)
    @accelleration = @thrust * @throttle
    
    new_speed = @speed + @accelleration
    if (new_speed <= @max_speed * @throttle)
      @speed = new_speed
    else
      @speed = @max_speed * @throttle
    end
    
    case @rotation_vector
    when -1
      self.rotation -= @rotation_speed
    when 1
      self.rotation += @rotation_speed
    end
    
    vec = Vector.new(@speed, @rotation)
    @position = @position + vec.point
  end
  
  def rotation=(value)
    value = value - 360 if (value > 359)
    value = value + 360 if (value < 0)
    
    @rotation = value
  end
  
  def width=(value)
    throw :out_of_range if value < 0
    @width = value
  end
  
  def height=(value)
    throw :out_of_range if value < 0
    @height = value
  end
  
  def hit?(point)
    bounds = self.rect
    return point.x > bounds[0] && point.y > bounds[1] && point.x < bounds[0] + bounds[2] && point.y < bounds[1] + bounds[3]
  end
  
  def rect
    [@position.x - (@width / 2), @position.y - (@height / 2), @width, @height]
  end
end